#
# CVSlog.py
#
# Wrapper around cvs log for SNiFF+ 3.x CVS Adapter
#
# Author: Martin Oberhuber
# Copyright (c) 1998, 1999 TakeFive Software, Salzburg
#
# Revisions:
#    1998/10/01  obi  Initial Version
#

import os, string, vcs
import CVSPrefs
from vcs import TRUE, FALSE, NL
from rlog import Rlog

SNIFF_BRANCH_PREFIX = 'SNIFF_BRANCH_'

class Cvslog(Rlog):
	CMD		= 'cvs log %s'
	filtered	= FALSE
	symbol_list = None
	def __init__(self, file, workFile, opt=''):
		# MOB--faster log handling by using rlog
		allFiles = string.split(file)
		if CVSPrefs.DoFastLog and len(allFiles) == 1:
			try:
				if CVSPrefs.TEST: print "CurDir: ",os.getcwd()
				RepFile = open("CVS/Repository","r")
				if CVSPrefs.TEST: print "RepFile: ",RepFile
				RepDir = string.strip(RepFile.read())
				RepFile.close()
				if CVSPrefs.TEST: print "RepDir: ",RepDir
				file = os.environ["SNIFF_SERVER"] + RepDir[2:] + "/" + file + ",v"
				print "(CVSlog) CVSlog: Doing rlog for ",file
				self.CMD = 'rlog %s'
			except:
				print "(CVSlog) CVSlog: Exception while trying to do fast rlog for ",file,": reverting to cvs."
		else:
			self.CMD = 'cvs log %s'
		return Rlog.__init__(self, file, workFile, opt)
	def symbolstr(self):
		my_debug_symList = self.symbollist()
		if my_debug_symList:
			return string.join(my_debug_symList, NL)
		else:
			return ""
	def symbollist(self):
		if self.filtered:
			return self.symbol_list
		if self.symbolic_names:
			symlist = string.split(self.symbolic_names, NL)
		else:
			symlist = []
		result = []
		for symdef in symlist:
			sym, rev = string.split(symdef)
			sym, rev = self._convert_rev(sym, rev)
			if rev and self.revision(rev):
				result.append(string.join((sym,rev)))
		self.symbol_list = result
		self.filtered = TRUE
		return self.symbol_list
	def _convert_rev(self, sym, rev):
		rl = string.split(rev, '.')
		if len(rl) < 3:
			return sym, rev
		if rev=='1.1.1':
			return SNIFF_BRANCH_PREFIX + sym, '1.1.1.1'
		if rl[-2]=='0':		# magic branch
			rl[-2] = rl[-1]
			rl[-1] = '1'
			sym = SNIFF_BRANCH_PREFIX + sym
		return sym, string.join(rl, '.')
	def next(self):
		# when multiple files are concerned, need to re-convert for new file
		Rlog.next(self)
		self.symbol_list = None
		self.filtered = FALSE
	def open(self, cmd, file):
		oldErr=vcs.err
		self.log = vcs.popen(cmd, file)
		if vcs.err != oldErr:
			# ignore error message printed by cvs log in case
			# "nothing is known about a file"
			# this can, for instance happen, during CheckIn of
			# a file that should be added on a branch - because
			# here, SNiFF requests a log although
			# "CheckRepositoryFile" is false
			cvsErr = string.strip(vcs.err[len(oldErr):])
			goodErr = "cvs log: nothing known about"
			if cvsErr[:len(goodErr)] == goodErr:
				if CVSPrefs.TEST:
					print "(CVSlog) @B",cmd, file,"@B ignoring error msg: ", vcs.err
				vcs.err = oldErr
		self.closed=FALSE
	def work_file(self):
		# CVS always returns correct workingFile also for FileType Dirs!
		return self.working_file
		# -- following code is obsolete -- probably for old CVS versions!
		if len(self.workFiles) <= 1:
			# fast result for single file log
			return self.workFiles[0]
		# multiple files:
		# it's possible that CVS re-sorts the list of files given!
		# We need the workfile including the FileType Directory,
		# therefore we need to sort it out. Attention: Can a file with the
		# Same name be in different FileType Directories? Basically yes...
		result = []
		for dirfile in self.workFiles:
			#print "Test :",dirfile,":",self.working_file,":"
			if os.path.basename(dirfile) == self.working_file:
				L = len(dirfile)
				#print "Test :",self.rcs_file,":"
				if self.rcs_file[-L-2:-2] == dirfile:
					return dirfile
				else:
					result.append(dirfile, self.rcs_file)
		if not result:
			print "CVSlog ERROR: could not match workfile!"
			return self.workFiles[self.count-1]
			#return self.working_file
		elif len(result) > 1:
			print "CVSlog ERROR: multiple matches: ",result
		(dirfile, rcsfile) = result[0]
		return dirfile
